package zrpc

import (
	"context"
	"fmt"
	"net"
	"net/rpc"
	"sync"

	"gitee.com/shijingzhao/go-frame/zlog"
)

func NewServer(ctx context.Context, config SerConfig) *Server {
	addr, err := net.ResolveTCPAddr("tcp", config.Addr)
	if err != nil {
		panic(any(fmt.Sprintf("rpc服务端:启动失败[%s]", err.Error())))
	}

	lis, err := net.ListenTCP("tcp", addr)
	if err != nil {
		panic(any(fmt.Sprintf("rpc服务端:监听异常[%s]", err.Error())))
	}

	ser := rpc.NewServer()

	return &Server{
		ctx:      ctx,
		config:   config,
		ser:      ser,
		lis:      lis,
		Handlers: make([]Handler, 0),
	}
}

// AddHandler 添加远程调用方法
//
//	ser.AddHandler([]Handler{
//	    {"GET", "/hello1", Hello1},
//	    {"GET", "/hello2", Hello2},
//	})
func (ser *Server) AddHandler(handlers []Handler) {
	for _, handler := range handlers {
		ser.Handlers = append(ser.Handlers, handler)

		if err := ser.ser.Register(handler.Obj); err != nil {
			panic(any(fmt.Sprintf("rpc服务端:注册RPC服务失败[%s]", err.Error())))
		}
	}
}

// AddMiddlewareHandler 添加带中间件的远程调用方法
//
//	ser.AddMiddlewareHandler([]Middleware{
//	    MiddlewareHello1,
//	    MiddlewareHello2,
//	}, []Handler{
//
//	    {"GET", "/hello1", Hello1},
//	    {"GET", "/hello2", Hello2},
//	})
//
// 顺序:MiddlewareHello1(MiddlewareHello2(HandlerFunc()))
func (ser *Server) AddMiddlewareHandler(middlewares []Middleware, handlers []Handler) {
	ser.AddHandler(MiddlewareRoutes(middlewares, handlers))
}

func (ser *Server) Start(wg *sync.WaitGroup) {
	wg.Add(1)
	go func() {
		defer wg.Done()
		for {
			conn, err := ser.lis.Accept()
			if err != nil {
				if err.(*net.OpError).Err == net.ErrClosed {
					return
				}
				zlog.NewSystem(ser.ctx).Error("rpc服务器:终止错误", zlog.String("s.lis.Accept.err", err.Error()))
				continue
			}
			go ser.ser.ServeConn(conn)
		}
	}()
}

// Close 终止
func (ser *Server) Close() bool {
	if err := ser.lis.Close(); err != nil {
		zlog.NewSystem(ser.ctx).Error("rpc服务器:关闭tcp监听异常", zlog.String("s.lis.Close.err", err.Error()))
		return false
	} else {
		return true
	}
}
